package com.hww.common.util;

import static android.Manifest.permission.CALL_PHONE;

import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.Settings;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresPermission;
import androidx.core.content.FileProvider;

import com.hww.common.MyAppThis;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public final class IntentUtils {

    private IntentUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * 判断给定的Intent是否可用
     *
     * @param intent The intent.
     * @return {@code true}: 可用<br>{@code false}: 不可用
     */
    public static boolean isIntentAvailable(final Intent intent) {
        return MyAppThis.getThis()
                .getPackageManager()
                .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
                .size() > 0;
    }

    /**
     * 获取一个用于安装应用的Intent
     * {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
     *
     * @param filePath 文件路径
     */
    public static Intent getInstallAppIntent(final String filePath) {
        return getInstallAppIntent(FileUtils.getFileByPath(filePath));
    }

    /**
     * 获取一个用于安装应用的Intent
     * {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
     *
     * @param file 应用文件
     */
    public static Intent getInstallAppIntent(final File file) {
        if (!FileUtils.isFileExists(file)) return null;
        Uri uri;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            uri = Uri.fromFile(file);
        } else {
            String authority = MyAppThis.getThis().getPackageName() + ".file_provider";
            uri = FileProvider.getUriForFile(MyAppThis.getThis(), authority, file);
        }
        return getInstallAppIntent(uri);
    }

    /**
     * 获取一个用于安装应用的Intent
     * <p>
     * {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
     */
    public static Intent getInstallAppIntent(final Uri uri) {
        if (uri == null) {
            return null;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        String type = "application/vnd.android.package-archive";
        intent.setDataAndType(uri, type);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        return intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    }

    /**
     * 获取一个用于卸载应用的Intent
     * Must hold {@code <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />}</p>
     *
     * @param pkgName 应用的包名.
     * @return
     */
    public static Intent getUninstallAppIntent(final String pkgName) {
        Intent intent = new Intent(Intent.ACTION_DELETE);
        intent.setData(Uri.parse("package:" + pkgName));
        return intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    }


    /**
     * Return the intent of launch app details settings.
     *
     * @param pkgName The name of the package.
     * @return the intent of launch app details settings
     */
    public static Intent getLaunchAppDetailsSettingsIntent(final String pkgName) {
        return getLaunchAppDetailsSettingsIntent(pkgName, false);
    }

    /**
     * 启动应用详情设置界面
     *
     * @param pkgName 应用包名
     * @return 返回Intent
     */
    public static Intent getLaunchAppDetailsSettingsIntent(final String pkgName, final boolean isNewTask) {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + pkgName));
        return getIntent(intent, isNewTask);
    }

    /**
     * 获取分享文本的Intent
     *
     * @param content 分享的文本内容.
     * @return 返回Intent
     */
    public static Intent getShareTextIntent(final String content) {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");
        intent.putExtra(Intent.EXTRA_TEXT, content);
        intent = Intent.createChooser(intent, "");
        return getIntent(intent, true);
    }

    /**
     * 返回分享图片的Intent
     *
     * @param imagePath 图片路径
     */
    public static Intent getShareImageIntent(final String imagePath) {
        return getShareTextImageIntent("", imagePath);
    }

    /**
     * 返回分享图片的Intent
     *
     * @param imageFile 图片文件.
     */
    public static Intent getShareImageIntent(final File imageFile) {
        return getShareTextImageIntent("", imageFile);
    }

    /**
     * 返回分享图片的Intent
     *
     * @param imageUri uri类型的图片路径
     */
    public static Intent getShareImageIntent(final Uri imageUri) {
        return getShareTextImageIntent("", imageUri);
    }

    /**
     * 获取一个分享文本和图片的Intent
     *
     * @param content   内容
     * @param imagePath 图片路径
     */
    public static Intent getShareTextImageIntent(@Nullable final String content, final String imagePath) {
        return getShareTextImageIntent(content, FileUtils.getFileByPath(imagePath));
    }

    /**
     * 获取一个分享文本和图片的Intent
     */
    public static Intent getShareTextImageIntent(@Nullable final String content, final File imageFile) {
        return getShareTextImageIntent(content, UriUtils.file2Uri(imageFile));
    }

    /**
     * 获取一个分享文本和图片的Intent
     */
    public static Intent getShareTextImageIntent(@Nullable final String content, final Uri imageUri) {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_TEXT, content);
        intent.putExtra(Intent.EXTRA_STREAM, imageUri);
        intent.setType("image/*");
        intent = Intent.createChooser(intent, "");
        return getIntent(intent, true);
    }

    /**
     * 获取一个分享多张图片的Intent
     */
    public static Intent getShareImageIntent(final LinkedList<String> imagePaths) {
        return getShareTextImageIntent("", imagePaths);
    }

    /**
     * 获取一个分享多张图片的Intent
     */
    public static Intent getShareImageIntent(final List<File> images) {
        return getShareTextImageIntent("", images);
    }

    /**
     * 获取一个分享多张图片的Intent
     */
    public static Intent getShareImageIntent(final ArrayList<Uri> uris) {
        return getShareTextImageIntent("", uris);
    }

    /**
     * 获取一个分享文本内容与多张图片的Intent
     */
    public static Intent getShareTextImageIntent(@Nullable final String content,
                                                 final LinkedList<String> imagePaths) {
        List<File> files = new ArrayList<>();
        if (imagePaths != null) {
            for (String imagePath : imagePaths) {
                File file = FileUtils.getFileByPath(imagePath);
                if (file != null) {
                    files.add(file);
                }
            }
        }
        return getShareTextImageIntent(content, files);
    }

    /**
     * 获取一个分享文本内容与多张图片的Intent
     */
    public static Intent getShareTextImageIntent(@Nullable final String content, final List<File> images) {
        ArrayList<Uri> uris = new ArrayList<>();
        if (images != null) {
            for (File image : images) {
                Uri uri = UriUtils.file2Uri(image);
                if (uri != null) {
                    uris.add(uri);
                }
            }
        }
        return getShareTextImageIntent(content, uris);
    }

    /**
     * 获取一个分享文本内容与多张图片的Intent
     */
    public static Intent getShareTextImageIntent(@Nullable final String content, final ArrayList<Uri> uris) {
        Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
        intent.putExtra(Intent.EXTRA_TEXT, content);
        intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
        intent.setType("image/*");
        intent = Intent.createChooser(intent, "");
        return getIntent(intent, true);
    }

    /**
     * 获取一个指定组件的Intent
     */
    public static Intent getComponentIntent(final String pkgName, final String className) {
        return getComponentIntent(pkgName, className, null, false);
    }

    /**
     * 获取一个指定组件的Intent
     */
    public static Intent getComponentIntent(final String pkgName,
                                            final String className,
                                            final boolean isNewTask) {
        return getComponentIntent(pkgName, className, null, isNewTask);
    }

    /**
     * 获取一个指定组件的Intent
     */
    public static Intent getComponentIntent(final String pkgName,
                                            final String className,
                                            final Bundle bundle) {
        return getComponentIntent(pkgName, className, bundle, false);
    }

    /**
     * 获取一个指定组件的Intent
     */
    public static Intent getComponentIntent(final String pkgName,
                                            final String className,
                                            final Bundle bundle,
                                            final boolean isNewTask) {
        Intent intent = new Intent();
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        ComponentName cn = new ComponentName(pkgName, className);
        intent.setComponent(cn);
        return getIntent(intent, isNewTask);
    }

    /**
     * 获取一个关机的Intent
     * android.intent.extra.KEY_CONFIRM false表示不需要用户确认关机操作
     */
    public static Intent getShutdownIntent() {
        Intent intent;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            intent = new Intent("com.android.internal.intent.action.REQUEST_SHUTDOWN");
        } else {
            intent = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
        }
        intent.putExtra("android.intent.extra.KEY_CONFIRM", false);
        return intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    }

    /**
     * 获取一个拨号盘打电话的Intent
     *
     * @param phoneNumber 手机号码
     */
    public static Intent getDialIntent(@NonNull final String phoneNumber) {
        Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + Uri.encode(phoneNumber)));
        return getIntent(intent, true);
    }

    /**
     * 获取一个拨打电话的Intent
     * <p>Must hold {@code <uses-permission android:name="android.permission.CALL_PHONE" />}</p>
     */
    @RequiresPermission(CALL_PHONE)
    public static Intent getCallIntent(@NonNull final String phoneNumber) {
        Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + Uri.encode(phoneNumber)));
        return getIntent(intent, true);
    }

    /**
     * 获取一个发送短信的Intent
     */
    public static Intent getSendSmsIntent(@NonNull final String phoneNumber, final String content) {
        Uri uri = Uri.parse("smsto:" + Uri.encode(phoneNumber));
        Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
        intent.putExtra("sms_body", content);
        return getIntent(intent, true);
    }

    /**
     * 获取一个拍照意图的Intent，打开相机
     */
    public static Intent getCaptureIntent(final Uri outUri) {
        return getCaptureIntent(outUri, false);
    }

    /**
     * 获取一个拍照意图的Intent，打开相机
     *
     * @param outUri    拍照后照片的输出路径
     * @param isNewTask 是否开启新的任务栈
     */
    public static Intent getCaptureIntent(final Uri outUri, final boolean isNewTask) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outUri);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        return getIntent(intent, isNewTask);
    }

    private static Intent getIntent(final Intent intent, final boolean isNewTask) {
        return isNewTask ? intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) : intent;
    }

    /**
     * 获取选择照片的 Intent
     *
     * @return
     */
    public static Intent getPickIntentWithGallery() {
        Intent intent = new Intent(Intent.ACTION_PICK);
        return intent.setType("image*//*");
    }

    /**
     * 获取从文件中选择照片的 Intent
     *
     * @return
     */
    public static Intent getPickIntentWithDocuments() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        return intent.setType("image*//*");
    }


    public static Intent buildImageGetIntent(final Uri saveTo, final int outputX, final int outputY, final boolean returnData) {
        return buildImageGetIntent(saveTo, 1, 1, outputX, outputY, returnData);
    }

    /**
     * 构建一个用于选择图片的Intent。
     * 根据Android版本的不同，使用ACTION_GET_CONTENT或ACTION_OPEN_DOCUMENT来获取图片。
     * 此Intent用于选择图片，并可以指定图片的保存位置、宽高比例及输出大小等参数。
     *
     * @param saveTo     保存选择图片的Uri，用于指定图片的保存位置。
     * @param aspectX    指定选择图片时的宽高比例的X值。
     * @param aspectY    指定选择图片时的宽高比例的Y值。
     * @param outputX    指定处理后图片的宽度。
     * @param outputY    指定处理后图片的高度。
     * @param returnData 指示是否返回数据，如果为true，则返回选择的图片数据。
     * @return 返回一个用于选择图片的Intent。
     */
    public static Intent buildImageGetIntent(Uri saveTo, int aspectX, int aspectY,
                                             int outputX, int outputY, boolean returnData) {
        Intent intent = new Intent();
        // 根据Android版本选择不同的Action，低于API 19使用ACTION_GET_CONTENT，否则使用ACTION_OPEN_DOCUMENT
        if (Build.VERSION.SDK_INT < 19) {
            intent.setAction(Intent.ACTION_GET_CONTENT);
        } else {
            intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
        }
        // 指定Intent的类型为图片
        intent.setType("image*//*");
        intent.putExtra("output", saveTo);
        intent.putExtra("aspectX", aspectX);
        intent.putExtra("aspectY", aspectY);
        intent.putExtra("outputX", outputX);
        intent.putExtra("outputY", outputY);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", returnData);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
        return intent;
    }

    public static Intent buildImageCropIntent(final Uri uriFrom, final Uri uriTo, final int outputX, final int outputY, final boolean returnData) {
        return buildImageCropIntent(uriFrom, uriTo, 1, 1, outputX, outputY, returnData);
    }

    /**
     * 构建一个用于裁剪图片的Intent。
     * <p>
     * 此方法旨在创建一个intent，用于启动图片裁剪功能。裁剪操作会按照指定的宽高比例、输出尺寸以及是否返回裁剪数据来进行。
     *
     * @param uriFrom    要裁剪的图片的源URI。
     * @param uriTo      裁剪后的图片保存的URI。
     * @param aspectX    裁剪框的宽度比例。
     * @param aspectY    裁剪框的高度比例。
     * @param outputX    裁剪后输出图片的宽度。
     * @param outputY    裁剪后输出图片的高度。
     * @param returnData 是否返回裁剪后的数据。如果为true，裁剪后的数据将通过Intent返回；如果为false，裁剪后的图片将保存到指定的uriTo路径下。
     * @return 返回一个用于裁剪图片的Intent。
     */
    public static Intent buildImageCropIntent(Uri uriFrom, Uri uriTo, int aspectX, int aspectY,
                                              int outputX, int outputY, boolean returnData) {
        // 创建一个Intent，指定动作是裁剪图片。
        Intent intent = new Intent("com.android.camera.action.CROP");
        // 设置要裁剪的图片的URI和类型。
        intent.setDataAndType(uriFrom, "image/*");
        // 指定这是一个裁剪操作。
        intent.putExtra("crop", "true");
        // 指定裁剪后的图片保存的URI。
        intent.putExtra("output", uriTo);
        // 指定裁剪框的宽高比例。
        intent.putExtra("aspectX", aspectX);
        intent.putExtra("aspectY", aspectY);
        // 指定裁剪后输出图片的尺寸。
        intent.putExtra("outputX", outputX);
        intent.putExtra("outputY", outputY);
        // 开启图片缩放功能。
        intent.putExtra("scale", true);
        // 指定是否通过Intent返回裁剪后的数据。
        intent.putExtra("return-data", returnData);
        // 指定输出图片的格式为PNG。
        intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
        // 返回构建好的Intent。
        return intent;
    }

    public static Intent buildImageCaptureIntent(final Uri uri) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        return intent;
    }
}
